function jumpToAnchor(anchor) {
	window.location.hash = anchor;
};

var UTF16 = {
	decode: function(str) {
		if (str == null) {
			return null
		}
		var hex2dec = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15};
		var new_str = "";
		var start = 0;
		var current = -1;
		var utf16_string = "";
		var utf16_code = null;
		var c = "";
		while ((current = str.indexOf('\\u00', start)) != -1 ) {
			utf16_string = str.substr(current, 6);
			if (utf16_string.length == 6) {
				utf16_code = hex2dec[utf16_string[4].toLowerCase()]*16 + hex2dec[utf16_string[5].toLowerCase()];
			}
			if (utf16_code) {
				c = String.fromCharCode(utf16_code);
			}
			
			new_str += str.substr(start, current-start) + c;
			start = current + 6;  
		};
		new_str += str.substr(start, str.length - start);
		return new_str;
	},
};

$(function() {
	function filter_node(node, click_type) {
		if (click_type == 'right') {
			node = node.getParents()[0];
		}
		var filter = $('#cooccur_paging_container').parent().children('.filter').first();
		filter.children('.clear_button').first().click();
		var search_term = "";
		if (node.id == 'root') {
			search_term = '';
		}
		else if (node.id.substring(3,5) == '++') {
			search_term = (click_type == 'right')? '': node.id.substring(0, 2);
		}
		else if (node.id.substring(3,5) == 'xx') {
			search_term = (click_type == 'right')? node.id.substring(0, 2): node.id.substring(0, 3);
		}
		else {
			search_term = node.id;
		}
		filter.children('.search_box').first().val(search_term + '');
		filter.children('.header_select').first().children('option').each(function() {
			if ($(this).val() == 'id') {
				$(this).attr('selected', true);
			}
			else {
				$(this).attr('selected', false);
			}
		});
		filter.children('.search_button').first().click();
	};
	
	var tm_options = {
		//where to inject the visualization
		injectInto: 'cooccur_treemap',
		//show only one tree level
		levelsToShow: 1,
		//parent box title heights
		titleHeight: 0,
		//enable animations
		animate: true,
		//box offsets
		offset: 1,
		//use canvas text
		Label: {
		  // type: labelType,
		  type: 'HTML',
		  size: 10,
		  family: 'Tahoma, Verdana, Arial',
		},
		//enable specific canvas styles
		//when rendering nodes
		Node: {
		  CanvasStyles: {
		    shadowBlur: 0,
		    shadowColor: '#000'
		  }
		},
		//Attach left and right click events
		Events: {
		  enable: true,
		  onClick: function(node, eventInfo, e) {
		    if (node)   {
				if (!tm.busy) {
					filter_node(node);
				}
				if (e.target.nodeName != 'A'){
					tm.enter(node);
				}
			}
		  },
		  onRightClick: function(node, eventInfo, e) {
			if (!tm.busy){
				filter_node(node, 'right');
			}
		    tm.out();
		  },
		  //change node styles and canvas styles
		  //when hovering a node
		  onMouseEnter: function(node, eventInfo) {
		    if(node) {
		      //add node selected styles and replot node
		      node.setCanvasStyle('shadowBlur', 7);
		      tm.fx.plotNode(node, tm.canvas);
		      // tm.labels.plotLabel(tm.canvas, node);
		      tm.labels.plotLabel(tm.canvas, node, tm.controller);
		    }
		  },
		  onMouseLeave: function(node) {
			   if(node) {
			     node.removeCanvasStyle('shadowBlur');
			     tm.plot();
			     }
			 }
		   },
     	//duration of the animations
	    duration: 200,
	    //Enable tips
	    	    Tips: {
	    	      enable: true,
	    	      type: 'Native',
	    	      //add positioning offsets
	    	      offsetX: 30,
	    	      offsetY: -80,
	    	      //implement the onShow method to
	    	      //add content to the tooltip when a node
	    	      //is hovered
	    	    	onShow: function(tip, node, isLeaf, domElement) {
	    	        	var html = '<div class="tip-title center">' + node.id + '</div>'
						+ '<div class="center">Total: ' + node.data.grand_total + '</div>'
	    		         + '<div class="tip-text" align="left">';
	    				html += '<ul>';
	    				for (var i in node.data.defns){
	    					html += '<li>' + node.data.defns[i].defnText + '</li>';
	    				}
	    			       tip.innerHTML =  html + '</ul>' + "</div>"; 
	    			 }  
	    	},
	    //Implement this method for retrieving a requested  
	    //subtree that has as root a node with id = nodeId,  
	    //and level as depth. This method could also make a server-side  
	    //call for the requested subtree. When completed, the onComplete   
	    //callback method should be called.  
		request: function(nodeId, level, onComplete){  
			var tree = jQuery.parseJSON(UTF16.decode($("#cooccur_tm_data").html()));
			var subtree = $jit.json.getSubtree(tree, nodeId);
			$jit.json.prune(subtree, 1);
			onComplete.onComplete(nodeId, subtree); 
		},
		onBeforePlotNode: function(node){
		},
	    //Add the name of the node in the corresponding label
	    //This method is called once, on label creation and only for DOM labels.
	    onCreateLabel: function(domElement, node){
			node.setData('color', '#FFF8C6');
			var html = '<div><div class="center" style="margin: 2px"><a href="/msc/' 
			+ node.id + '">' + node.id + '</a> (' + node.data.grand_total +') </div>';
			for (var i in node.data.defns){
				html += '<div> >>' + node.data.defns[i].defnText + '</div>';
			}
			html += '</div>';
			domElement.innerHTML = html;
	    },
		onAfterCompute: function() {
			$('#log').html('');
			// make_tag_links();
		},
	};
	// init treemap
	var tm = new $jit.TM.Squarified(tm_options);
	// load data
	var json = jQuery.parseJSON(UTF16.decode($("#cooccur_tm_data").html()));
	$jit.json.prune(json, 1)
	tm.loadJSON(json);
	tm.refresh();
	
});





/////////////////////////////////////////
// year plot
$(function () {
	var data = jQuery.parseJSON(UTF16.decode($("#year_data").html()));
	var plot_data = [];
	for (var i in data) {
		plot_data.push([parseInt(data[i]['year']), parseInt(data[i]['count'])]);
	}
	plot_data.sort(function (a, b) {
		return (a < b) ? -1 : (a == b)? 0: 1;
	});
	data = plot_data;
	var options = {
		series: {
			stack: 0,
			bars: { show: true, barWidth: 0.9},
			points: { show: false },
		},
		grid:{ 
			// backgroundColor: { colors: ["#ffff", "#eeee"] },
			hoverable: true,
			clickable: true,
			borderWidth: 0,
		},
	
	};
    $.plot($("#year_plot"), [data], options);

  	function showTooltip(x, y, contents) {
       $('<div id="year_plot_tooltip">' + contents + '</div>').css( {
           position: 'absolute',
           display: 'none',
           top: y - 35,
           left: x + 10,
           border: '1px solid #fdd',
           padding: '2px',
           'background-color': '#fee',
           opacity: 0.80
       }).appendTo("body").fadeIn(200);
	}
	var previousPoint = null;
	$("#year_plot").bind("plotclick", function (event, pos, item){
		if (item) {
			var x = item.datapoint[0];
            var y = item.datapoint[1];
			var filter = $('#year_paging_container').parent().children('.filter').first();
			filter.children('.clear_button').first().click();
			filter.children('.search_box').first().val(x + '');
			filter.children('.header_select').first().children('option').each(function() {
				if ($(this).val() == 'year') {
					$(this).attr('selected', true);
				}
				else {
					$(this).attr('selected', false);
				}
			});
			filter.children('.search_button').first().click();
		}
	});
	$("#year_plot").bind("plothover", function (event, pos, item) {
	    if (item) {
               if (previousPoint != item.datapoint) {
                   previousPoint = item.datapoint;
                 
                   $("#year_plot_tooltip").remove();
                   var x = item.datapoint[0],
                       y = item.datapoint[1];
                 
                   showTooltip(pos.pageX, pos.pageY,
                               "Year:" + parseInt(x) + " | Count:" + parseInt(y));
               }
           }
           else {
               $("#year_plot_tooltip").remove();
               previousPoint = null;            
           }
	})

});


// author cloud
// $(function () {
// 	var data = jQuery.parseJSON(UTF16.decode($("#author_data").html()));
// 	var MAX_LEVEL = 10;
// 	var increment = 2; 
// 	var min_level = 0; 
// 	
// 	
// 	// reverse mapping data
// 	var rev_data = {};
// 	var counts = []
// 	for (var i in data) {
// 		var count = data[i]['count'];
// 		if (!rev_data[count]) {
// 			rev_data[count] = [];
// 			counts.push(count);
// 		}
// 		rev_data[count].push(data[i]);
// 	}
// 	
// 	// normalize tag size
// 	if (counts.length < 4) {increment=6;}
// 	else if (counts.length < 5) {increment=5;}
// 	else if (counts.length < 6) {increment=4; }
// 	if (counts.length < MAX_LEVEL) {
// 		for (var index in counts) {
// 			var count = counts[index];
// 			for (var j in rev_data[count]) {
// 				rev_data[count][j]['size'] = min_level + index * increment;
// 			}
// 		}
// 	}
// 	else {
// 		for (var index in counts) {
// 			var count = counts[index];
// 			for (var j in rev_data[count]) {
// 				rev_data[count][j]['size'] = min_level + increment * parseInt(index * (MAX_LEVEL / counts.length));
// 			}		
// 		}
// 	}
// 	
// 	// sort data according to author name
// 	data.sort(function (x, y) {
// 		return (x['name'] < y['name'])? -1 : (x['name'] == y['name'])? 0 : 1;
// 	});
// 	
// 	var tag_cloud = $('<ul class="tag_cloud"></ul>');
// 	for (var i in data) {
// 		var cls = (i % 2 == 0)? 'even': 'odd';
// 		var tag = $('<li><a href="#author_cloud">' + data[i]['name'] + '</a></li>');
// 		tag.children('a').first().addClass(cls);
// 		tag.addClass('tag' + data[i]['size']);
// 		tag.appendTo(tag_cloud);
// 	}
// 	tag_cloud.appendTo($('#author_cloud'))
// });



// generate pagination tables for cooccurrences, years and authors
$(function() {
	var items_per_page = 10;
	var max_rows = 100;
	var num_display_entries = 7;
	
	var paginationOptions = {
		items_per_page : items_per_page,
		num_display_entries : num_display_entries,
		num_edge_entries: 1,
		callback: function(new_page_index, pagination_container) {
			var data = $(pagination_container).data('paging_data');
			if ($(pagination_container).data('filtered_paging_data')) {
				data = $(pagination_container).data('filtered_paging_data');
			}
			var sort_table = $(pagination_container).data('sort_table');
			if (sort_table) {
				var sort_func = sort_table['sort_func'];
				var key = sort_table['key'];
				var desc = sort_table['desc'];
				sort_func(data, key, desc);
			}
			var headers = $(pagination_container).data('headers'); // [[headerText1, id1], [headerText2, id2], ...]

			// create filter
			if ($('.filter', $(pagination_container).parent()).length == 0) {
				var filter = $('<div class="filter"></div>');
				var options = '<SELECT class="header_select">';
				for (var h in headers) {
					options += '<OPTION value="' + headers[h][1] + '">' + headers[h][0] + '</OPTION>';
				}
				options += '</SELECT>';
				filter.append($(options));		
				var search_box = $('<input class="search_box" type="text"/>').appendTo(filter);
				var filter_button = $('<button class="filter_button search_button">Filter</button>');
				filter_button.click(function() {
					var data = $(pagination_container).data('paging_data');
					var header = $(':selected', $(pagination_container).parent().children('.filter').find('select').first()).val();
					var value = $('.search_box', $(pagination_container).parent().children('.filter').first()).val();
					value = value.toLowerCase();
					var result = [];
					if (value == '') {
						result = data;
					}
					else {
						for (var i in data) {
							var doc = data[i];
							if (doc[header]) {
								var header_val = doc[header] + '';
								header_val = header_val.toLowerCase();
								if ( (value.length <= (header_val.length)) && (value == header_val.substring(0, value.length))) {
									result.push(doc);
								}
							}
						}
					}
					$(pagination_container).data('filtered_paging_data', result);
					$(pagination_container).pagination(result.length, paginationOptions);
					return false;
				});
				filter_button.appendTo(filter);
				var clear_button = $('<button class="clear_button">Clear</button>');
				clear_button.click(function() {
					$(pagination_container).data('filtered_paging_data', null);
					$(pagination_container).parent().children('.filter').first().children('.search_box').first().val("");
					var data = $(pagination_container).data('paging_data');
					$(pagination_container).pagination(data.length, paginationOptions);
				});
				clear_button.appendTo(filter);
				filter.appendTo($(pagination_container).parent());
			}
			// end of creating filter
			
			// create content
			$('.pagination_content', $(pagination_container).parent()).remove();
			var table = $('<table class="pagination_content"></table>');
			var thead = $('<thead></thead>');
			for (h in headers) {
				var key = headers[h][1];
				var header = $('<th>' + headers[h][0] + '</th>');
				header.data('key', key);
				if (($(pagination_container).data('sort_table')) && ($(pagination_container).data('sort_table')['key'] == key)) {
					cls = ($(pagination_container).data('sort_table')['desc'])? 'desc' : 'asc';
					header.addClass(cls);
				}
				// enable sorting
				var sort_func = function (data, key, desc) {
					data.sort(function(x, y) {
						result = (x[key] < y[key])? -1: (x[key] == y[key])? 0: 1;
						if (desc) { result = -result;}
						return result;
					});
				}
				header.click(function() {
					var desc;
					if ($(this).hasClass('desc')) {
						$(this).removeClass('desc');
						$(this).addClass('asc');
						desc = false;
					}
					else {
						$(this).removeClass('asc');
						$(this).addClass('desc');
						desc = true;
					}
					$(pagination_container).data('sort_table', {
						sort_func: sort_func,
						key: $(this).data('key'),
						desc: desc
					});
					$(pagination_container).pagination(data.length, paginationOptions);
				});
				// end of enabling sorting
				
				header.css('cursor', 'pointer');
				header.appendTo(thead);
			}
			thead.appendTo(table);
			var tbody = $('<tbody></tbody>');
			for (var i=new_page_index*items_per_page; i < Math.min(data.length, (new_page_index + 1)*items_per_page, max_rows); i++) {
				var doc = data[i];
				if (doc) {
					var html = '<tr>';
					for (h in headers) {
						key = headers[h][1];
						html += '<td>';
						html += doc[key] ? doc[key]: '';
						html += '</td>';
					}
					html += '</tr>';
				}
				$(html).appendTo(tbody);
			}
			tbody.appendTo(table);
			var pagination_content = table;
			
			
			
			// var html = '<table class="pagination_content"><thead><tr>';
			// 			for (h in headers) {
			// 				header_text = headers[h][0];
			// 				html += '<th>' + header_text + '</th>'
			// 			}
			// 			html += '</tr></thead><tbody>';
			// 			for (var i=new_page_index*items_per_page; i < Math.min((new_page_index + 1)*items_per_page, max_rows); i++) {
			// 				var doc = data[i];
			// 				if (doc) {
			// 					html += '<tr>';
			// 					for (h in headers) {
			// 						key = headers[h][1];
			// 						html += '<td>';
			// 						html += doc[key] ? doc[key]: '';
			// 						html += '</td>';
			// 					}
			// 					html += '</tr>';
			// 				}
			// 			}
			// 			html += '</tbody></table>';
			// 			var pagination_content = $(html);
			// end of creating content
			

			
			// create hyperlink effect
			var cell_indexes = {};
			var hyperlinked_cells = $(pagination_container).data('hyperlinked_cells')
			for (var i in headers) {
				for (var j in hyperlinked_cells) {
					if (headers[i][1] == hyperlinked_cells[j]) {
						cell_indexes[i] = true;
					}
				}
			}
			pagination_content.find('tbody tr td').each(function () {
				var index = $(this).attr('cellIndex');
				if (cell_indexes[index]) {
					$(this).css('text-decoration', 'underline');
					$(this).css('cursor', 'pointer');
					$(this).hover(
						function() {
							$(this).html('<a href="/msc/' + $(this).text() + '">' + $(this).text() + '</a>');
						},
						function() {
							$(this).html($(this).text());
						}
					);
				}
			});
			
			
			pagination_content.appendTo($(pagination_container).parent());
			},
		};
		
	// init pagination for cooccurences
	var data = jQuery.parseJSON(UTF16.decode($("#cooccur_data").html()));
	var selector = '#cooccur_paging_container';
	var headers = [['Tag', 'id'], ['Count', 'count'], ['Description', 'tagText']];
	$(selector).data('paging_data', data);
	$(selector).data('headers', headers);
	$(selector).data('hyperlinked_cells', ['id']);
	if (data) {
		paginationOptions['link_to'] = selector;
		$(selector).pagination(data.length, paginationOptions);
	}

	
	// init pagination for years
	var data = jQuery.parseJSON(UTF16.decode($("#year_data").html()));
	var selector = '#year_paging_container';
	var headers = [['Year', 'year'], ['Count', 'count']];
	$(selector).data('paging_data', data);
	$(selector).data('headers', headers);
	if (data) {
		paginationOptions['link_to'] = selector;
		$(selector).pagination(data.length, paginationOptions);
	}
	
	// init pagination for authors
	var data = jQuery.parseJSON(UTF16.decode($("#author_data").html()));
	var selector = '#author_paging_container';
	var headers = [['Name', 'name'], ['Count', 'count']];
	$(selector).data('paging_data', data);
	$(selector).data('headers', headers);
	if (data) {
		paginationOptions['link_to'] = selector;
		$(selector).pagination(data.length, paginationOptions);
	}
});


